/*
 * GammaElias.cpp
 *
 *  Created on: 6/12/2012
 *      Author: d
 */

#include "GammaElias.h"

GammaElias::GammaElias(){

}


size_t GammaElias::compress( const byte* datoAcomprimir, byte* datoComprimido, size_t tamanioDelDato ){
			int tamanioDeArrayDeBytes=0;
			ColeccionDeBytes* coleccionDeBytes=new ColeccionDeBytes();
			ColeccionDeBits* coleccionDeBits=new ColeccionDeBits();
			byte dato;
			
			for(size_t i=0;i<tamanioDelDato;i++){

			//accedo al iesimo elemento del dato a comprimir y lo guardo en una variable
			dato=*(datoAcomprimir+i);
			

			Compresor* compresor=new Compresor(dato);
			
			//devuelve una colecci�n de n bits cuyos primeros cuatro bits indican la longitud en bits de la codificaci�n
			ColeccionDeBits* codificacionEnBits=compresor->comprimir();

			coleccionDeBits->concatenarCon(codificacionEnBits);

			}
			//separa una colecci�n de bits en uno o m�s bytes y los agrega a la colecci�n de bytes
			coleccionDeBytes->normalizar(coleccionDeBits);

			Byte* cadaByte;
			for(int j=0;j<coleccionDeBytes->tamanio();j++){
			cadaByte=coleccionDeBytes->obtener(j);
			
			//guardo en el iesimo elemento del dato comprimido la representacion decimal de cada byte de la colecci�n
			*(datoComprimido+j)=cadaByte->obtenerRepresentacionDecimal();

			tamanioDeArrayDeBytes=j;
			}
			if(tamanioDeArrayDeBytes!=0) tamanioDeArrayDeBytes++; //para que no cuente desede cero sino desde 1
			return tamanioDeArrayDeBytes;
		}
		
size_t  GammaElias::uncompress( const byte* datoComprimido, byte* datoDescomprimido,size_t tamanioDelDato ){

			int tamanioDeArrayDeBytes=0;
			ColeccionDeBits* coleccionDeBits=new ColeccionDeBits();
			Utilidades utilidades =Utilidades();
			ColeccionDeBits* representacionBinaria=new ColeccionDeBits();
			int cantidadDeBytesALeer;

			byte dato;
			size_t i=0;
			int k=0;
			int indiceDeBytes=0;

			while(i<tamanioDelDato){
				Byte* unByte=new Byte();
				ColeccionDeBytes* coleccionDeBytes=new ColeccionDeBytes();
			//accedo al iesimo elemento del dato a descomprimir y lo guardo en una variable
			dato=*(datoComprimido+i);
			


			representacionBinaria=utilidades.obtenerRepresentacionBinariaDe(dato);
			//si la coleccion de bits(representacion binaria)es menor a ocho rellena con ceros adelante
			unByte->extensionAIzquierda(representacionBinaria);//TODO
			coleccionDeBits=unByte->obtenerColeccionDeBits();
			cantidadDeBytesALeer=utilidades.obtenerRepresentacionDecimalDe(coleccionDeBits->obtenerPrimerosCuatroBits());
			int limiteDelIndiceDeBytes=cantidadDeBytesALeer+indiceDeBytes;


			
			coleccionDeBytes->agregarAlFinal(unByte);//TODO

			indiceDeBytes=i+1;
			while(indiceDeBytes<limiteDelIndiceDeBytes){

				Byte* elByte=new Byte();
				//accedo al iesimo elemento del dato a descomprimir y lo guardo en una variable
				dato=*(datoComprimido+indiceDeBytes);

				representacionBinaria=utilidades.obtenerRepresentacionBinariaDe(dato);

				//si la coleccion de bits(representacion binaria)es menor a ocho rellena con con ceros adelante
				elByte->extensionAIzquierda(representacionBinaria);//TODO
			
				coleccionDeBytes->agregarAlFinal(elByte);//TODO
				indiceDeBytes++;

			}
			i=indiceDeBytes;


			
			Descompresor* descompresor=new Descompresor(coleccionDeBytes->obtenerColeccionDeBits());//TODO

			//devuelve la codificacion en representacion decimal
			int codificacionEnRepresentacionDecimal=descompresor->descomprimir();

			//guardo en el iesimo elemento del dato descomprimido la representacion decimal
			*(datoDescomprimido+k)=codificacionEnRepresentacionDecimal;

			tamanioDeArrayDeBytes=k;
			k++;
			}
			if(tamanioDeArrayDeBytes!=0) tamanioDeArrayDeBytes++; //para que no cuente desede cero sino desde 1
			return tamanioDeArrayDeBytes;

}	

GammaElias::~GammaElias(){

}

